package org.phonetic.aspect;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;

import org.application.bean.PacienteDao;
import org.application.model.Paciente;
import org.phonetic.model.PacientePhoneticCode;
import org.phonetic.model.PhoneticCode;

import br.com.p2d.phonetizer.FonetizacaoBR;

public aspect PhoneticUpdate {

	declare warning : execution( void PacienteDao.update(..)) : "A implementação deste método foi alterada pelo aspecto org.phonetic.aspect.PhoneticUpdate";

	pointcut executeUpdate(Paciente user, PacienteDao dao) 
	: execution( void PacienteDao.update(Paciente)) && args(user) && target(dao);

	after(Paciente o, PacienteDao dao)  returning : executeUpdate(o, dao){
		execute(o, dao);
	}

	private void execute(Paciente o, PacienteDao dao) {
		EntityManager entityManager = dao.getEntityManager();
		String query = "SELECT ppc FROM PacientePhoneticCode ppc WHERE ppc.paciente.id = :id";
		@SuppressWarnings("unchecked")
		List<PacientePhoneticCode> codes = entityManager.createQuery(query)
				.setParameter("id", o.getId()).getResultList();
		for (PacientePhoneticCode code : codes) {
			entityManager.remove(code);
		}
		ArrayList<String> strings = FonetizacaoBR.makeAllPhoneticCodes(o
				.getNome());
		for (String string : strings) {
			entityManager.getTransaction().begin();
			PhoneticCode phoneticCode = null;
			try {
				phoneticCode = (PhoneticCode) entityManager
						.createQuery(
								"SELECT pc FROM PhoneticCode pc WHERE pc.hash = :hash")
						.setParameter("hash", string).getSingleResult();
			} catch (NoResultException e) {
				phoneticCode = new PhoneticCode();
				phoneticCode.setHash(string);
				entityManager.persist(phoneticCode);
				entityManager.refresh(phoneticCode);
			}
			PacientePhoneticCode relacionamento = new PacientePhoneticCode();
			relacionamento.setPhoneticCode(phoneticCode);
			relacionamento.setPaciente(o);
			entityManager.persist(relacionamento);
			entityManager.getTransaction().commit();
		}
	}

}
